{-# LANGUAGE ScopedTypeVariables, TemplateHaskell #-}
module Tests.DescaleBarsTest where
-- module Main where

-- imports
import Types
import Distribution.DescaleBars
import Test.QuickCheck
import Test.QuickCheck.All
import Control.Monad
import Data.Time

instance Arbitrary BarData where
        arbitrary = liftM5 BarData arbitrary arbitrary arbitrary arbitrary arbitrary

fakeUtcTime = UTCTime (ModifiedJulianDay 0) 0

-- descale tests
prop_descale_single b = descale [(fakeUtcTime, b)] == b
intDescale a b = descale [(fakeUtcTime, a), (fakeUtcTime, b)]
prop_descale_high a b = barHigh (intDescale a b) == (max (barHigh a) (barHigh b))
prop_descale_low a b = barLow (intDescale a b) == (min (barLow a) (barLow b))
prop_descale_open a b = barOpen (intDescale a b) == barOpen a
prop_descale_close a b = barClose (intDescale a b) == barClose b

-- filter tests
instance Arbitrary UTCTime where
        arbitrary = liftM2 UTCTime arbitrary genSeconds
                where  genSeconds = liftM secondsToDiffTime arbitrary

instance Arbitrary Day where
        arbitrary = liftM (fromGregorian 2011 02) (elements [1..28])
        
instance Arbitrary LocalTime where
        arbitrary = liftM2 LocalTime arbitrary arbitrary

instance Arbitrary TimeOfDay where
        arbitrary = liftM2 shortCut (elements [0..23]) (elements [0..59])
                where shortCut x y = TimeOfDay x y 0.0

prop_addOneHour t = (diffUTCTime added orig) == fromInteger 3600
        where   added   = localTimeToUTC utc $ addOneHour t
                orig    = localTimeToUTC utc t 
 
isInDay d (t, b)  = (utctDay t == d)

prop_filter_day d xs = any (isInDay d) xs ==> all (isInDay d) (filterDay d xs)
prop_filter_day_idm d xs = any (isInDay d) xs ==> filterDay d (filterDay d xs) == filterDay d xs
prop_filter_day_null d xs = not (any (isInDay d) xs) ==> filterDay d xs == []

isInHour h (t, b) = (todHour . localTimeOfDay . utcToLocalTime utc) t == (todHour . localTimeOfDay) h

prop_filter_hour_idm h xs = any (isInHour h) xs ==> filterHour h (filterHour h xs) == filterHour h xs
prop_filter_hour h xs = any (isInHour h) xs ==> all (isInHour h) (filterHour h xs)
prop_filter_hour_null h xs = not (any (isInHour h) xs) ==> (filterHour h xs) == []

main = $(quickCheckAll)